package eigenfiles;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Scanner;


public class Printer {

	public static void writeState(String path, State state) throws Exception {
		BufferedWriter out;
		try {
			out = new BufferedWriter(new FileWriter(path, true));
		} catch (IOException e1) {
			writeState(path, state);
			return;
		}
		try {
			String[] controlChars 	= controlChars(); // 0:start, 1: stop
			out.append(controlChars[0]);
			out.newLine();
			Method[] methods = state.getClass().getDeclaredMethods();
			Field[] fields = state.getClass().getDeclaredFields();
			for (Field field : fields) {
				String fieldName = field.getName();
				String getMethoden = "get" + fieldName;
				Method method = SportSettings.findMethod(getMethoden, methods);
				out.append(fieldName + " = " + method.invoke(state, null));
				out.newLine();
			} // end for
			out.append(controlChars[1]);
			out.newLine();
		} catch (IOException e) {
			writeState(path, state);
			return;
		} catch (IllegalArgumentException e) {
			writeState(path, state);
			return;
		} catch (IllegalAccessException e) {
			writeState(path, state);
			return;
		} catch (InvocationTargetException e) {
			writeState(path, state);
			return;
		} finally{
			out.close();
		}
		out.close();

	}
	public static State readState(String path) {
		State state = new State();
		BufferedReader inputStream;
		try {
			inputStream = new BufferedReader(new FileReader(path));
		} catch (IOException e1) {
			//
			return null;
		}
		String[] controlChars 	= controlChars(); // 0: start, 1: stop

		Method[] methods 		= State.class.getDeclaredMethods();
		Field[] fields 			= State.class.getDeclaredFields();
		int size 				= fields.length + 2;
		String[] lines 			= new String[size];
		try{
			for (int i = 0; i < size; i++) {
				lines[i] = inputStream.readLine();
			}
		} catch(IOException e){
			// TODO catch exception
		}
		if(!lines[0].equals(controlChars[0]) || !lines[size-1].equals(controlChars[1])){
			// file is corrupt, retrun default state, TODO verbeteren
			return State.defState();
		}
		for (int i = 0; i < size-1; i++) { 
			if((i == 0) || (i == size-1)){
				// skip first and last lines
				continue;
			}
			try {
				Scanner s = new Scanner(lines[i]);
				String methodName = "set" + s.next();
				Method method = SportSettings.findMethod(methodName, methods);
				s.next(); // equals sign

				Object args[] 	= new Object[1];
				args[0] 		= s.nextInt();
				method.invoke(state, args);
			} catch (IllegalArgumentException e) {
				// corrupt
				System.err.println("IllegelArgEx");
				continue;
			} catch (Exception e) {
				// corrupt
				return State.defState();
			}		
		}
		return state;
	}

	private static String[] controlChars() {
		String startSeperator 	= "<begin>";	// 0
		String stopSeperator 	= "<end>";		// 1
		String[] controlChars 	= {startSeperator, stopSeperator};
		return controlChars;
	}

	public static void main(String[] args) {
		testPrinter();
	}
	private static void testPrinter() {
		String path = "C:/Users/Jochem/workspace/Scorebord/scoreboard_state.txt";
		State stateIn = testWrite(path);

		State stateOut = testRead(path);

	}
	private static State testRead(String path) {
		return readState(path);
	}
	private static State testWrite(String path) {
		new State();
		State state = State.dummyState();
		try {
			writeState(path, state);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return null;
		}
		return state;
	}

}
